package com.hqq.concurrency.reactor.framework;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

/**
 * NIOServerSocketChannel
 * 接受TCP连接的通道
 * Created by heqianqian on 2017/8/5.
 */
public class NIOServerSocketChannel extends AbstractNIOChannel {

    private static final Logger LOGGER = LoggerFactory.getLogger(NIOServerSocketChannel.class);

    private int port;

    /**
     * 创建一个新的通道
     *
     * @param port    端口号
     * @param handler 处理器
     */
    public NIOServerSocketChannel(int port, ChannelHandler handler) throws IOException {
        super(ServerSocketChannel.open(), handler);
        this.port = port;
    }

    @Override
    public int getInterestedOps() {
        return SelectionKey.OP_ACCEPT;
    }

    /**
     * 将TCP套接字绑定到指定的端口
     */
    @Override
    public void bind() throws IOException {
        ((ServerSocketChannel) getJavaChannel()).socket().bind(new InetSocketAddress(InetAddress.getLocalHost(), port));
        getJavaChannel().configureBlocking(false);
        LOGGER.info("Bind Socket at port {}", port);
    }

    @Override
    public ByteBuffer read(SelectionKey key) throws IOException {
        SocketChannel channel = (SocketChannel) key.channel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        buffer.flip();//从头开始读取
        int read = channel.read(buffer);
        if (read == -1) {
            throw new IOException("Socket closed");
        }
        return buffer;
    }

    @Override
    protected void doWrite(Object pendingWrite, SelectionKey key) throws IOException {
        ByteBuffer buffer = (ByteBuffer) pendingWrite;
        ((SocketChannel) key.channel()).write(buffer);
    }
}
